package cn.snsprj.authclient.util;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * httpClient工具类
 *
 * @author SKH
 * @date 2018-06-07 14:59
 **/
public class HttpUtil {

    private static Logger logger = LoggerFactory.getLogger(HttpUtil.class);

    private static final String utf8 = "utf-8";

    /**
     * httpClient get 请求
     *
     * @param url url
     * @return
     */
    public static String doGet(String url) {
        return doGet(url, null);
    }

    /**
     * httpClient get 请求
     *
     * @param url url
     * @return String
     */
    public static String doGet(String url, Map<String, Object> parmMap) {

        logger.info("====> request url is {}", url);

        try {
            String protocol = StringUtils.substringBefore(url, ":");
            if (StringUtils.equals(protocol, "http")) {
                // http request

                CloseableHttpClient httpclient = HttpClients.createDefault();

                HttpGet httpGet = new HttpGet(parseParms(url, parmMap));
                try (CloseableHttpResponse response = httpclient.execute(httpGet)){

                    HttpEntity entity = response.getEntity();

                    return EntityUtils.toString(entity, "UTF-8");

                }catch (Exception ex){
                    ex.printStackTrace();
                    return null;
                }

            } else {
                // TODO https request
                return null;
            }

        } catch (Exception ex) {

            ex.printStackTrace();
            return null;
        }
    }


    /**
     * httpClient post 请求
     *
     * @param url url
     * @param parasMap 请求参数
     * @return String
     */
    public static String doPost(String url, Map<String, Object> parasMap) {

        return null;
    }

    /**
     * @param request HttpUriRequest,get/post
     * @return String
     * @throws IOException IOException
     */
    private static String execute(HttpUriRequest request) throws IOException {

        String result = "";

        CloseableHttpClient httpclient = HttpClients.createDefault();

        try (CloseableHttpResponse response = httpclient.execute(request)) {

            logger.info(response.getStatusLine().toString());

            HttpEntity entity = response.getEntity();

            if (entity != null) {
                result = EntityUtils.toString(entity, utf8);
                logger.info("====> result is {}", result);
            }
            // do something useful with the response body
            // and ensure it is fully consumed
            EntityUtils.consume(entity);
        }
        return result;
    }

    /**
     * 构造 http GET 请求参数
     *
     * @param parmMap 请求参数
     * @return UrlEncodedFormEntity
     */
    private static URI parseParms(String url, Map<String, Object> parmMap)
            throws URISyntaxException {

        URIBuilder uriBuilder = new URIBuilder(url);

        List<NameValuePair> nvps = new ArrayList<>();

        if (parmMap != null && !parmMap.isEmpty()) {

            for (Entry<String, Object> entry : parmMap.entrySet()) {

                String key = entry.getKey();
                Object value = entry.getValue();

                if (value instanceof String || value instanceof Number || value instanceof Date) {

                    nvps.add(new BasicNameValuePair(key, String.valueOf(value)));

                } else {

                    String json = JsonUtil.obj2String(value);
                    nvps.add(new BasicNameValuePair(key, json));
                }
            }
        }

        uriBuilder.setParameters(nvps);

        return uriBuilder.build();
    }
}
